import * as d3 from '../../../static/js/d3.v3.min'
function JusTree2(params) {
  this.width = params.width ? params.width : document.querySelector(params.divId).offsetWidth
  this.height = params.height ? params.height : document.querySelector(params.divId).offsetHeight
  this.divId = params.divId
  this.data = params.data || []
  this.lineColor = '#000000'
  this.examplesFontColor = '#000000'
  this.lineFontSize = 10
  this.nodesFontSize = 16
}
JusTree2.prototype = {
  init: function () {
    this.drawChart()
  },
  drawChart: function () {
    try {
      let nodes = this.data.nodes
      let relationColor = this.data.relationColor
      let links = this.data.links
      let main = this.data.title
      nodes = d3.values(nodes)
      relationColor = d3.values(relationColor)
      nodes.forEach(item => {
        links.forEach(items => {
          if (item.name === items.source.name) {
            item[items.target.name] = { name: items.target.name }
          }
          if (item.name === items.target.name) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
            item[items.source.name] = { name: items.source.name }
          }
        })
      })
      var examplesx = parseFloat(20) // 关系示例坐标x
      var examplesy = parseFloat(40) // 关系示例坐标y
      var examplesLength = 20
      var examplesSize = Math.floor((this.height - examplesy) / examplesLength)
      for (var i = 1; i <= relationColor.length; i++) {
        var num = i % examplesSize === 0 ? examplesSize : i % examplesSize
        relationColor[i - 1].x = examplesx
        relationColor[i - 1].y = examplesy + (num - 1) * examplesLength
      }
      var zoom = d3.behavior.zoom()
        .scaleExtent([-2, 1.5])
        .on("zoom", zoomed)
      var svg = d3.select(this.divId).append("svg").call(zoom)
        .attr("width", this.width)
        .attr("height", this.height)
        .attr("transform", function () {
          return "translate(0)"
        })
        .attr('viewBox', `0 0 ${this.width} ${this.height}`)
        .attr('preserveAspectRatiz', 'xMinYMin meet')
        .on('dblclick.zoom', null)
        .on("mousedown.zoom", null)
        .on('click', function () {
          if (d3.event.defaultPrevented) return;
          d3.selectAll('circle').style('stroke-width', '2px').style('stroke', "")
          edgesText.style("fill-opacity", function (edge) {
            return 1
          })
          circle.style("opacity", function (edge) {
            return 1
          })
          edgesPath.style("opacity", function (edge) {
            return 1
          })
          nodesText.style("opacity", function (edge) {
            return 1
          })
        })
      
      var examples = svg.selectAll(".examples")
        .data(relationColor)
        .enter()
        .append("svg:g")
        .attr("fill-opacity", function (d) {
          return 1
        })
      examples.append("svg:path")
        .attr("d", function (d) {
          var x1 = d.x
          var y1 = d.y
          var x2 = x1 + 5
          var y2 = y1
          return `M${x1} ${y1} L${x2} ${y2}`
        })
        .style("stroke", function (d) {
          return d.lineColor
        })
        .style("stroke-width", 12)
        .style("stroke-linecap", 'round')
      examples.append("svg:text")
        .style("font-size", "14px")
        .style("fill", this.examplesFontColor)
        .attr("x", function (d) {
          return d.x + 25 + 14 * d.relation.length / 2
        })
        .attr("y", function (d) {
          return d.y + 5
        })
        .attr('text-anchor', "middle")
        .text(function (d) {
          return d.relation
        })
      var force = d3.layout.force()
        .size([this.width, this.height])
        .alpha(0.1)
        .theta(0)
        // .linkDistance([200]) // 连线长度
        // .charge([-1500])
        .linkDistance(200) // 连线长度
        .charge(-1500)
        // -Infinity
        // .start()
        // setTimeout(function () {
        //   force.stop()
        // }, 15000)
        // 手动快速布局
      var drag = force.drag().on("dragstart", function (d, i) {
        if (d3.event.defaultPrevented) return;
        d.fixed = true
      })
      var edgesPath = svg.selectAll(".edgepath")
        .data(links)
        .enter()
        .append("path")
        .attr("marker-end", function (d, i) {
          var arrowMarker = svg.append("marker")
            .attr("id", "arrow" + i)
            .attr("markerUnits", "userSpaceOnUse")
            .attr("markerWidth", "16")
            .attr("markerHeight", "15")
            .attr("viewBox", "0 0 12 12")
            .attr("refX", 9)
            .attr("refY", 6)
            .attr("orient", "auto")
            .append("svg:path")
            .attr("d", "M2,2 L10,6 L2,10 L6,6 L2,2")
            .attr("fill", function () {
              return d.lineColor === "" ? this.lineColor : d.lineColor
            })
          return "url(#arrow" + i + ")"
        })
        .style("stroke", function (d) {
          if (d.lineColor === "") {
            return this.lineColor
          } else {
            return d.lineColor
          }
        })
        .style("stroke-width", 3)
        .attr({ 'class': 'edgepath', 'id': function (d, i) { return 'edgepath' + i } })

      var edgesText = svg.append("g").selectAll(".edgelabel")
        .data(links)
        .enter()
        .append("text")
        .attr({ 'class': 'edgelabel', 'id': function (d, i) { return 'edgepath' + i }, 'dx': 50, 'dy': '3px' })
        .attr("fill-opacity", 1)
        
      force
        .nodes(nodes)
        .links(links)
      force.start()
      for (let i = 0, n = 1000; i < n; ++i) {
        force.tick()
      }
      // 停止力布局
      force.stop()
      // 固定所有节点
      nodes.forEach(node => {
        node.fixed = true
      })
      edgesText.append('textPath')
        .attr('xlink:href', function (d, i) { return '#edgepath' + i })
        .style("font-size", (this.lineFontSize + "px"))
        .style("fill", "#000")
        .attr('text-anchor', "middle")
        .attr('pointer-event', "none")
        .text(function (d) {
          return d.relation
        })

      var circle = svg.selectAll("circle")
        .data(nodes)
        .enter()
        .append("circle")
        .style('opacity', function (d) {
          if (d.name == main) {
            try {
              // 初始化隐藏其他连接线上的文字
              edgesText.style("fill-opacity", function (edge) {
                if (edge.source === d || edge.target === d) {
                  return 1
                }
                if (edge.source !== d && edge.target !== d) {
                  return 0
                }
              })
              // 初始化隐藏其他连线
              edgesPath.style("opacity", function (edge) {
                if (edge.source === d || edge.target === d) {
                  return 1
                }
                if (edge.source !== d && edge.target !== d) {
                  return 0
                }
              })
            } catch (err) {
              console.log(err)
            }
          }
          if (d.name == main || (d[main] != undefined && d[main].name == main)) { //初始化只展示一级关系节点
            return 1
          } else {
            return 0
          }
        })
        .style("stroke-width", "2px")
        .attr("r", function (d) {
          if (d.isMain) {
            return d.radius + 3
          } else {
            return d.radius  
          }
        })
        .attr('title', function (d) {
          return d.name
        })
        .attr('cursor', function (d) {
          return (d.isRisk !== 'false' && !d.isMain) ? 'pointer' : 'all'
        })
        .attr("fill", function (d, i) {
          if (d.isMain) {// 如果是主体 
            return '#FF9F00'
          }
          if (d.type === 'person') {
            // 如果节点是人 显示为砖红色并且缩小半径
            // return '#5e9df3'砖红色
            return '#9EEA6A'
          } else {
            if (d.isRisk !== 'false' && !d.isMain) {
              // 如果有风险 显示红色填充
              return '#ff0000'
            }
            return "#84A5EF"// 企业节点给浅蓝色
          }
        })
        .on("mouseover", function (d) {
          d3.event.stopPropagation()
          if (d3.event.defaultPrevented) return;
          circle.style("stroke-width", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '3px'
            } else {
              return '2px'
            }
          })
          circle.style("stroke", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '#EFB6D4'
            } else {
              return ''
            }
          })
        })
        .on("click", function (d) {
          d3.event.stopPropagation()
          if (d3.event.defaultPrevented) return;
          circle.style("stroke-width", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '3px'
            } else {
              return '2px'
            }
          })
          circle.style("stroke", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '#EFB6D4'
            } else {
              return ''
            }
          })
          // 隐藏其它连线上文字
          edgesText.style("fill-opacity", function (edge) {
            if (edge.source === d || edge.target === d) {
              return 1
            }
            if (edge.source !== d && edge.target !== d) {
              return 0
            }
          })
          // 其它节点亮度调低
          circle.style("opacity", function (edge) {
            var v = d.name
            if (edge.name == v || (edge[v] != undefined && edge[v].name == v)) {
              return 1
            } else {
              return 0.2
            }
          })
          // 隐藏其它连线
          edgesPath.style("opacity", function (edge) {
            if (edge.source === d || edge.target === d) {
              return 1
            }
            if (edge.source !== d && edge.target !== d) {
              return 0
            }
          })
          // 隐藏其它节点文字
          nodesText.style("opacity", function (edge) {
            var v = d.name
            if (edge.name == v || (edge[v] != undefined && edge[v].name == v)) {
              return 1
            } else {
              return 0
            }
          })
          // 图谱新功能
        })
        .call(drag)
      let nodesFontSize = this.nodesFontSize
      var nodesText = svg.selectAll(".nodetext")
        .data(nodes)
        .enter()
        .append("text")
        .style("font-size", (nodesFontSize + "px"))
        .attr("fill", function (d) {
          return 'white'
        })
        .attr('cursor', function (d) {
          return (d.isRisk !== 'false' && !d.isMain) ? 'pointer' : ''
        })
        .style("opacity", function (edge) {
          if (edge.name == main || (edge[main] != undefined && edge[main].name == main)) {
            return 1
          } else {
            return 0
          }
        })
        .on("mouseover", function (d) {
          d3.event.stopPropagation()
          if (d3.event.defaultPrevented) return;
          circle.style("stroke-width", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '3px'
            } else {
              return '2px'
            }
          })
          circle.style("stroke", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '#EFB6D4'
            } else {
              return ''
            }
          })
        })
        .on("click", function (d) {
          d3.event.stopPropagation()
          if (d3.event.defaultPrevented) return;
          circle.style("stroke-width", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '3px'
            } else {
              return '2px'
            }
          })
          circle.style("stroke", function (edge) {
            var v = d.name
            if (edge.name == v) {
              return '#EFB6D4'
            } else {
              return ''
            }
          })
          // 隐藏其它连线上文字
          edgesText.style("fill-opacity", function (edge) {
            if (edge.source === d || edge.target === d) {
              return 1
            }
            if (edge.source !== d && edge.target !== d) {
              return 0
            }
          })
          // 其它节点亮度调低
          circle.style("opacity", function (edge) {
            var v = d.name
            if (edge.name == v || (edge[v] != undefined && edge[v].name == v)) {
              return 1
            } else {
              return 0.2
            }
          })
          // 隐藏其它连线
          edgesPath.style("opacity", function (edge) {
            if (edge.source === d || edge.target === d) {
              return 1
            }
            if (edge.source !== d && edge.target !== d) {
              return 0
            }
          })
          // 隐藏其它节点文字
          nodesText.style("opacity", function (edge) {
            var v = d.name
            if (edge.name == v || (edge[v] != undefined && edge[v].name == v)) {
              return 1
            } else {
              return 0
            }
          })
        })
        .on('dblclick', function (d) {
          d3.event.stopPropagation()
          if (d3.event.defaultPrevented) return;
          if (/*d.isRisk && */!d.isMain && d.type !== 'person') {
            let detailHref =
              'http://' +
              location.host +
              '#/entdetail/baseinfo?entname=' +
              d.name
            window.open(detailHref)
          }
        })
        .call(drag)
        .attr('x', function (d) {
          var name = d.name
          if (name.length < 4) {
            d3.select(this).append('tspan')
              .attr("dx", -nodesFontSize * (name.length / 2))
              .text(function () { return name })
          } else if (name.length >= 4 && name.length <= 6) {
            var top = d.name.substring(0, 3)
            var bot = d.name.substring(3, name.length)

            d3.select(this).append('tspan')
              .attr("dx", -nodesFontSize * 1.5)
              .attr("dy", -nodesFontSize * 0.5)
              .text(function () { return top })

            d3.select(this).append('tspan')
              .attr("dx", -(nodesFontSize * name.length / 2))
              .attr("dy", nodesFontSize)
              .text(function () { return bot })
          } else if (name.length > 7) {
            var top = d.name.substring(0, 3)
            var mid = d.name.substring(3, 6)
            var bot = d.name.substring(6, name.length)
            d3.select(this).append('tspan')
              .attr("dx", -nodesFontSize * 1.5)
              .attr("dy", -nodesFontSize * 0.5)
              .text(function () { return top })

            d3.select(this).append('tspan')
              .attr("dx", -nodesFontSize * 3)
              .attr("dy", nodesFontSize)
              .text(function () { return mid })

            d3.select(this).append('tspan')
              .attr("dx", -nodesFontSize * 2)
              .attr("dy", nodesFontSize)
              .text(function () { return "..." })
          }
        })
      function zoomed() {
        if (Math.ceil(zoom.scale()) <= 3) {
          circle.attr("transform",
            "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")")
          nodesText.attr("transform",
            "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")")
          edgesPath.attr("transform",
            "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")")
          transform()
          setTimeout(function () {
            force.stop()
          },1000)
        }
        // svg.attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale * 0.6 + ')')
      }
      let obj = Object.create({})
      links.forEach(item => {
        obj[item.source.name] === 1 ? (obj[item.source.name]++) : obj[item.source.name] === undefined ? obj[item.source.name] = 1 : (obj[item.source.name]++)
      })
      nodes.forEach(d => {
        if (d.isMain) {
          d.fixed = true
          d.coor = { x: 587, y: 320 }
        } else {
          if (obj.hasOwnProperty(d.name)) {
            if (obj[d.name] > 20) {
              d.coor = { x: 587 + Math.random() * 600 - 350, y: 320 + Math.random() * 600 - 350 }
              d.fixed = true
            }
          }
        }
      })
      function transform() {
        setTimeout(function () {
          force.stop()
        },1000)
        circle.attr("cx", function (d) {
          if (d.coor) {
            d.x = d.coor.x
          }
          return d.x
        })
        circle.attr("cy", function (d) {
          if (d.coor) {
            d.y = d.coor.y
          }
          return d.y
        })
        nodesText.attr("x", function (d) {
          if (d.coor) {
            d.x = d.coor.x
          }
          return d.x
        })
        nodesText.attr("y", function (d) {
          if (d.coor) {
            d.y = d.coor.y
          }
          return d.y
        })
        edgesPath.attr("d", function (d, i) {
          var tan = Math.abs((d.target.y - d.source.y) / (d.target.x - d.source.x)) // 圆心连线tan值
          var x1 = d.target.x - d.source.x > 0 ? Math.sqrt(d.sourceRadius * d.sourceRadius / (tan * tan + 1)) + d.source.x
            : d.source.x - Math.sqrt(d.sourceRadius * d.sourceRadius / (tan * tan + 1)) // 起点x坐标
          var y1 = d.target.y - d.source.y > 0 ? Math.sqrt(d.sourceRadius * d.sourceRadius * tan * tan / (tan * tan + 1)) + d.source.y
            : d.source.y - Math.sqrt(d.sourceRadius * d.sourceRadius * tan * tan / (tan * tan + 1)) // 起点y坐标
          var x2 = d.target.x - d.source.x > 0 ? d.target.x - Math.sqrt(d.targetRadius * d.targetRadius / (1 + tan * tan))
            : d.target.x + Math.sqrt(d.targetRadius * d.targetRadius / (1 + tan * tan))// 终点x坐标
          var y2 = d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt(d.targetRadius * d.targetRadius * tan * tan / (1 + tan * tan))
            : d.target.y + Math.sqrt(d.targetRadius * d.targetRadius * tan * tan / (1 + tan * tan))// 终点y坐标
          if (d.target.x - d.source.x == 0 || tan == 0) { // 斜率无穷大的情况或为0时
            y1 = d.target.y - d.source.y > 0 ? d.source.y + d.sourceRadius : d.source.y - d.sourceRadius
            y2 = d.target.y - d.source.y > 0 ? d.target.y - d.targetRadius : d.target.y + d.targetRadius
          }
          if (d.linknum === 0) { // 设置编号为0的连接线为直线，其他连接线会均分在两边
            d.x_start = x1
            d.y_start = y1
            d.x_end = x2
            d.y_end = y2
            return `M${x1} ${y1} L ${x2} ${y2}`
          }
          var a = d.sourceRadius > d.targetRadius ? d.targetRadius * d.linknum / 3 : d.sourceRadius * d.linknum / 3
          var xm = d.target.x - d.source.x > 0 ? d.source.x + Math.sqrt((d.sourceRadius * d.sourceRadius - a * a) / (1 + tan * tan))
            : d.source.x - Math.sqrt((d.sourceRadius * d.sourceRadius - a * a) / (1 + tan * tan))
          var ym = d.target.y - d.source.y > 0 ? d.source.y + Math.sqrt((d.sourceRadius * d.sourceRadius - a * a) * tan * tan / (1 + tan * tan))
            : d.source.y - Math.sqrt((d.sourceRadius * d.sourceRadius - a * a) * tan * tan / (1 + tan * tan))
          var xn = d.target.x - d.source.x > 0 ? d.target.x - Math.sqrt((d.targetRadius * d.targetRadius - a * a) / (1 + tan * tan))
            : d.target.x + Math.sqrt((d.targetRadius * d.targetRadius - a * a) / (1 + tan * tan))
          var yn = d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt((d.targetRadius * d.targetRadius - a * a) * tan * tan / (1 + tan * tan))
            : d.target.y + Math.sqrt((d.targetRadius * d.targetRadius - a * a) * tan * tan / (1 + tan * tan))
          if (d.target.x - d.source.x == 0 || tan == 0) { // 斜率无穷大或为0时
            ym = d.target.y - d.source.y > 0 ? d.source.y + Math.sqrt(d.sourceRadius * d.sourceRadius - a * a) : d.source.y - Math.sqrt(d.sourceRadius * d.sourceRadius - a * a)
            yn = d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt(d.targetRadius * d.targetRadius - a * a) : d.target.y + Math.sqrt(d.targetRadius * d.targetRadius - a * a)
          }

          var k = (x1 - x2) / (y2 - y1) // 连线垂线的斜率
          var dx = Math.sqrt(a * a / (1 + k * k)) // 相对垂点x轴距离
          var dy = Math.sqrt(a * a * k * k / (1 + k * k)) // 相对垂点y轴距离
          if ((y2 - y1) === 0) {
            dx = 0
            dy = Math.sqrt(a * a)
          }
          if (a > 0) {
            var xs = k > 0 ? xm - dx : xm + dx
            var ys = ym - dy
            var xt = k > 0 ? xn - dx : xn + dx
            var yt = yn - dy
          } else {
            var xs = k > 0 ? xm + dx : xm - dx
            var ys = ym + dy
            var xt = k > 0 ? xn + dx : xn - dx
            var yt = yn + dy
          }
          d.x_start = xs
          d.y_start = ys
          d.x_end = xt
          d.y_end = yt
          return `M${xs} ${ys} L ${xt} ${yt}`
        })
        edgesText.attr('transform', function (d, i) {
          if (d.target.x < d.source.x) {
            var bbox = this.getBBox();
            var rx = bbox.x + bbox.width / 2;
            var ry = bbox.y + bbox.height / 2;
            return 'rotate(180 ' + rx + ' ' + ry + ')';
          }
          else {
            return 'rotate(0)';
          }
        })
        .attr('dx', function (d, i) {
          return Math.sqrt(Math.pow(d.x_end - d.x_start, 2) + Math.pow(d.y_end - d.y_start, 2)) / 2;
        })
        setTimeout(function () {
          force.stop()
        },1000)
      }
      force.on('tick', function () {
        transform()
      })
    } catch (error) {
      console.log(error)
    }
  }
}
export default JusTree2



// WEBPACK FOOTER //
// ./src/assets/js/jus_tree2.js